﻿//************************************************************************************************
// Copyright © 2014 Steven M. Cohn. All Rights Reserved.
// 
//************************************************************************************************

namespace River.Folderize
{
	using System;
	using System.Drawing;
	using System.IO;
	using System.Text;
	using System.Windows;
	using System.Windows.Interop;
	using System.Windows.Media;
	using System.Windows.Media.Imaging;


	/// <summary>
	/// Some fundamental file system operations.
	/// </summary>

	internal static class ImageHelper
	{
		private const string DefaultFolderModule = "shell32.dll";
		private const string DefaultLibraryModule = "imageres.dll";

		private const int DefaultFolderResID = 3;
		private const int DefaultLibraryResID = -1001;

	
		/// <summary>
		/// 
		/// </summary>

		public enum ImageType
		{
			Folder,		// a file system folder
			Library,	// a library folder
			Absolute	// used by GetIcon to avoid infinite recursion
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="path"></param>
		/// <param name="type"></param>
		/// <returns></returns>

		public static ImageSource LoadIcon (string path, ImageType type)
		{
			string module;
			int index;

			SplitImageResourceString(path, out module, out index, type);
			return LoadIcon(module, index, type);
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="path"></param>
		/// <param name="index"></param>
		/// <param name="type"></param>
		/// <returns></returns>

		public static ImageSource LoadIcon (string path, int index, ImageType type)
		{
			if (path.IndexOf(Path.DirectorySeparatorChar) < 0)
			{
				path = Path.Combine(
					Environment.GetFolderPath(Environment.SpecialFolder.System),
					path);
			}
			else if (path.IndexOf('%') > 0)
			{
				path = Environment.ExpandEnvironmentVariables(path);
			}

			var handle = Native.ExtractIcon(0, path, index);
			if (handle != IntPtr.Zero)
			{
				var icon = Icon.FromHandle(handle);

				return Imaging.CreateBitmapSourceFromHIcon(
					icon.Handle,
					new Int32Rect(0, 0, icon.Width, icon.Height),
					BitmapSizeOptions.FromEmptyOptions());
			}

			if (type == ImageType.Folder)
			{
				if ((path != DefaultFolderModule) && (index != DefaultFolderResID))
				{
					return LoadIcon(DefaultFolderModule, DefaultFolderResID, ImageType.Absolute);
				}
			}
			else if (type == ImageType.Library)
			{
				if ((path != DefaultLibraryModule) && (index != DefaultLibraryResID))
				{
					return LoadIcon(DefaultLibraryModule, DefaultLibraryResID, ImageType.Absolute);
				}
			}

			return null;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="res"></param>
		/// <param name="module"></param>
		/// <param name="index"></param>
		/// <param name="type"></param>
		/// <returns></returns>

		public static bool PickIcon (string res, out string module, out int index, ImageType type)
		{
			ImageHelper.SplitImageResourceString(res, out module, out index, type);
			var builder = new StringBuilder(module, 512);

			int result = Native.PickIconDlg(
				new WindowInteropHelper(Application.Current.MainWindow).Handle,
				builder, builder.MaxCapacity, ref index);

			if (result > 0)
			{
				module = builder.ToString();
				return true;
			}

			return false;
		}
	
		
		/// <summary>
		/// Parse the given image resource string to return the path of the module in
		/// which the image is stored and the image table index or resource identifier
		/// used to lookup the image.
		/// </summary>
		/// <param name="res">The image resource string to parse.</param>
		/// <param name="path">A StringBuilder to which the module path is written.</param>
		/// <param name="index">An integer specifying the resource index or identifier.</param>
		/// <param name="type">The desired default image type if the res image is not found.</param>

		public static void SplitImageResourceString (
			string res, out string path, out int index, ImageType type)
		{
			path = null;
			index = 0;

			if (!String.IsNullOrEmpty(res))
			{
				var parts = res.Split(',');
				if ((parts.Length == 2) && !parts[1].StartsWith("DefaultIcon"))
				{
					if (Int32.TryParse(parts[1], out index))
					{
						if (parts[0].IndexOf('%') > -1)
						{
							path = Environment.ExpandEnvironmentVariables(parts[0]);
						}
						else
						{
							path = parts[0];
						}
					}
				}
			}

			if (path == null)
			{
				if (type == ImageType.Folder)
				{
					path = Path.Combine(
						Environment.GetFolderPath(Environment.SpecialFolder.System),
						DefaultFolderModule);

					index = DefaultFolderResID;
				}
				else if (type == ImageType.Library)
				{
					path = Path.Combine(
						Environment.GetFolderPath(Environment.SpecialFolder.System),
						DefaultLibraryModule);

					index = DefaultLibraryResID;
				}
			}
		}
	}
}
